/*
 * Copyright (c) 2006-2020, SZ-ZZS Development Team
 *
 *                            _ooOoo_
 *                           o8888888o
 *                           88" . "88
 *                           (| -_- |)
 *                           O\  =  /O
 *                        ____/`---'\____
 *                      .'  \\|     |//  `.
 *                     /  \\|||  :  |||//  \
 *                    /  _||||| -:- |||||-  \
 *                    |   | \\\  -  /// |   |
 *                    | \_|  ''\---/''  |   |
 *                    \  .-\__  `-`  ___/-. /
 *                  ___`. .'  /--.--\  `. . __
 *               ."" '<  `.___\_<|>_/___.'  >'"".
 *              | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *              \  \ `-.   \_ __\ /__ _/   .-` /  /
 *         ======`-.____`-.___\_____/___.-`____.-'======
 *                            `=---='
 *        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *                      Buddha Bless, No Bug !
 * Change Logs:
 * Date           Author       Notes
 * 2022-05-16  Urey       the first version
 */

/*
*********************************************************************************************************
*                                            INCLUDE FILES
*********************************************************************************************************
*/

#define    MB_TCP_MODULE
#include  <mb.h>

#define DBG_LVL     DBG_INFO
#define DBG_TAG     "mb.rtu"
#include <rtdbg.h>

#if (MODBUS_CFG_RTU_EN == DEF_ENABLED)

MODBUS_CH* MB_TcpCh(CPU_INT08U node_addr,
                    CPU_INT08U master_slave,
                    CPU_INT32U rx_timeout,
                    CPU_INT08U wr_en)
{
    MODBUS_CH *pch;

    if (MB_ChCtr < MODBUS_CFG_MAX_CH)
    {
        pch = &MB_ChTbl[MB_ChCtr];
        MB_MasterTimeoutSet(pch, rx_timeout);
        MB_NodeAddrSet(pch, node_addr);
        MB_ModeSet(pch, master_slave, MODBUS_MODE_TCP);
        MB_WrEnSet(pch, wr_en);

        MB_ChCtr++;
        return (pch);
    }
    else
    {
        return ((MODBUS_CH*) 0);
    }
}
#endif /* (MODBUS_CFG_RTU_EN == DEF_ENABLED) || (MODBUS_CFG_ASCII_EN == DEF_ENABLED)    */



#if (MODBUS_CFG_TCP_EN == DEF_ENABLED)
CPU_BOOLEAN  MB_TCP_Rx (MODBUS_CH  *pch)
{
    //事务处理标识
    //识别报文
    if((pch->RxBuf[2] != 0) || (pch->RxBuf[3] != 0))
    {
        LOG_E("frame type error");
        return DEF_FALSE;
    }

    rt_uint16_t pdu_len = 256L * pch->RxBuf[4] + pch->RxBuf[5];
    if(pdu_len >= (MODBUS_CFG_BUF_SIZE - 6))
    {
        LOG_E("PDU Length error");
        return DEF_FALSE;
    }

    rt_memcpy(pch->RxFrameData, pch->RxBuf + 6, pdu_len);
    pch->RxFrameNDataBytes = pdu_len - 2;       //MODBUS-TCP 无CRC校验

    return DEF_TRUE;
}


void  MB_TCP_Tx (MODBUS_CH  *pch)
{
    /* 事务标识 */
    pch->TxBuf[0] = pch->RxBuf[0];
    pch->TxBuf[1] = pch->RxBuf[1];
    /* 帧标识 */
    pch->TxBuf[2] = pch->RxBuf[2];
    pch->TxBuf[3] = pch->RxBuf[3];

    /* 数据长度
     *
     * 事务 2B  + 帧标识2B +总长度2B + 地址1B + 功能码1B + 数据长度1B + 数据NB
     * */
    rt_uint16_t pdu_len = pch->TxFrameNDataBytes + 2;
    if (pdu_len >= (MODBUS_CFG_BUF_SIZE - 6))
    {
        LOG_E("PDU Length error");
    }
    pch->TxBuf[4] = pdu_len / 256;
    pch->TxBuf[5] = pdu_len % 256;

    /* 地址 */
    /* 功能码 */
    /* 数据域 */
    memcpy(&pch->TxBuf[6],pch->TxFrameData,pdu_len);
    pch->TxBufByteCtr = pdu_len + 6;
    pch->TxBufPtr = &pch->TxBuf[0];

    //推送消息
//    rt_m

#if (MODBUS_CFG_MASTER_EN == DEF_ENABLED)
    if (pch->MasterSlave == MODBUS_MASTER)
    {
        pch->RxBufByteCtr = 0; /* Flush Rx buffer                                    */
    }
#endif

}

void MB_TCP_MsgPush(MODBUS_CH  *pch ,CPU_INT08U* rxBuf, CPU_INT16U rxSize)
{
    if(rxSize >= MODBUS_CFG_BUF_SIZE)
        rxSize = MODBUS_CFG_BUF_SIZE;

    rt_memcpy(pch->RxBuf, rxBuf, rxSize);
    pch->RxCtr = rxSize;
    pch->RxBufPtr = pch->RxBuf + rxSize;
    pch->RxBufByteCtr = rxSize;

    //notify rx task
    MB_OS_RxSignal(pch);
}


#endif /* (MODBUS_CFG_TCP_EN == DEF_ENABLED) */

